package com.qp;

import be.ac.ulg.montefiore.run.distributions.GaussianDistribution;
import be.ac.ulg.montefiore.run.jahmm.*;
import be.ac.ulg.montefiore.run.jahmm.apps.cli.CommandLineArguments;
import be.ac.ulg.montefiore.run.jahmm.apps.cli.Types;
import be.ac.ulg.montefiore.run.jahmm.apps.cli.WrongArgumentsException;
import be.ac.ulg.montefiore.run.jahmm.io.FileFormatException;
import com.em.EMForGaussians;
import com.em.EmForGaussiansResult;
import com.utils.Constants;
import com.utils.SequenceIterator;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: bigmar
 * Date: 12/18/14
 * Time: 9:33 AM
 * To change this template use File | Settings | File Templates.
 */
public class MainCaller
{

    private double[][] kMatrix;
    private double [][] cMatrix;
    private double [][] aMatrix;
    private double[] etaEstimation;
    private EmForGaussiansResult emForGaussiansResult;
    public<O extends Observation & CentroidFactory<O>> Hmm<O> call(String fileName, int numberOfModels) throws Exception
    {

//        InputStream seqStream = new FileInputStream("C:\\workspace\\jahmm-0.6.1\\new.seq");
        InputStream seqStream = new FileInputStream(fileName);
        Reader seqReader = new InputStreamReader(seqStream);
        CommandLineArguments.Arguments.OPDF.set("gaussian");
        CommandLineArguments.Arguments.OPDF.setIsSet(true);
        List<? extends List<? extends Observation>> seqs = Types.relatedObjs().readSequences(seqReader);


        SequenceIterator sequenceIterator=new SequenceIterator(seqs, Constants.numberOfObservations);
        emForGaussiansResult=new EMForGaussians(numberOfModels, Constants.numberOfObservations, sequenceIterator).run();

        ContionousOutputDistributionEstimator estimator=new ContionousOutputDistributionEstimator(emForGaussiansResult.getGaussianList(), emForGaussiansResult.getMixtureWeights(), sequenceIterator, Constants.numberOfObservations);
        etaEstimation=estimator.estimate();
//        for (int i=0; i<etaEstimation.length; ++i)
//            etaEstimation[i]*=1.8;
        kMatrix=OutputDistributionCalculator.calculate(emForGaussiansResult.getGaussianList());

        cMatrix=CMatrixCalculator.calculate(emForGaussiansResult.getMixtureWeights(), kMatrix);

        aMatrix=QPCaller.call(cMatrix, emForGaussiansResult.getMixtureWeights(), etaEstimation);

        List<Opdf> opdfs = new ArrayList<Opdf>(numberOfModels);
        for(OpdfGaussian gaussian:emForGaussiansResult.getGaussianList())
            opdfs.add(new OpdfGaussian(gaussian.mean(), gaussian.variance()));

        Hmm<O> hmm=new Hmm(emForGaussiansResult.getMixtureWeights(), aMatrix, opdfs);
        return hmm;
    }

    public double[][] getkMatrix()
    {
        return kMatrix;
    }

    public double[][] getcMatrix()
    {
        return cMatrix;
    }

    public double[] getEtaEstimation() {
        return etaEstimation;
    }

    public double[][] getaMatrix() {
        return aMatrix;
    }

    public EmForGaussiansResult getEmForGaussiansResult()
    {
        return emForGaussiansResult;
    }
}